package sim;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

public class Runner {
	
	public static void main(String args[]){
		
		//Parameters: filename, -p <int> - PROCCERSS_TIME, -s <int> - SEND_TINE, -d <int> - SEND_DELTA, -f <int> FIGHTBACK_DELAY
		if (args.length < 1){
			System.out.println("No filename detected.");
			printUsage();
			return;
		}
		for (int i = 1 ; i < args.length ; i+=2){
			if (args[i].equals("-p")){
				if (i+1 >= args.length){
					printUsage();
					return;
				}
				int p = Integer.parseInt(args[i+1]);
				if ( p > 0){
					Common.PROCESS_TIME = p;
				}
				else {
					System.out.println("Negative process time detected.");
					printUsage();
					return;
				}
			}
			if (args[i].equals("-s")){
				if (i+1 >= args.length){
					printUsage();
					return;
				}
				int s = Integer.parseInt(args[i+1]);
				if ( s > 0){
					Common.SEND_TIME = s;
				}
				else {
					System.out.println("Negative send time detected.");
					printUsage();
					return;
				}
			}
			if (args[i].equals("-d")){
				if (i+1 >= args.length){
					printUsage();
					return;
				}
				int d = Integer.parseInt(args[i+1]);
				if ( d > 0){
					Common.SEND_DELTA = d;
				}
				else {
					System.out.println("Negative send delta detected.");
					printUsage();
					return;
				}
			}
			if (args[i].equals("-f")){
				if (i+1 >= args.length){
					printUsage();
					return;
				}
				int f = Integer.parseInt(args[i+1]);
				if ( f > 0){
					Common.FIGHTBACK_DELAY = f;
				}
				else {
					System.out.println("Negative fightback delay detected.");
					printUsage();
					return;
				}
			}
			if (args[i].equals("-m")){
				if (i+1 >= args.length){
					printUsage();
					return;
				}
				int m = Integer.parseInt(args[i+1]);
				if ( m > 0){
					Common.MIN_LS = m;
				}
				else {
					System.out.println("Negative MinLSInterval delay detected.");
					printUsage();
					return;
				}
			}	
			if (args[i].equals("-r")){
				if (i+1 >= args.length){
					printUsage();
					return;
				}
				int r = Integer.parseInt(args[i+1]);
				if ( r > 0){
					Common.RETRANSMISSION = r;
				}
				else {
					System.out.println("Negative retransmission time delay detected.");
					printUsage();
					return;
				}
			}	
		}
		System.out.println("Running simulation on \'" + args[0] + "\' with parameters:");
		System.out.println("\tPacket process time: " + Common.PROCESS_TIME);
		System.out.println("\tPacket send time: " + Common.SEND_TIME);
		System.out.println("\tTime between trigger and false LSA: " + Common.SEND_DELTA);
		System.out.println("\tFightBack generation time: " + Common.FIGHTBACK_DELAY);
		System.out.println("\tMinLSInterval: " + Common.MIN_LS);
		System.out.println("\tRetransmission time: " + Common.RETRANSMISSION);
		runner(args[0]);
	}
	
	public static void printUsage(){
		System.out.println("Usage: filename -p <int> -s <int> -d <int>");
		System.out.println("Where:");
		System.out.println("\t-p = Packet proccess time (default = 50),");
		System.out.println("\t-s = Packet send time (default = 10),");
		System.out.println("\t-d = Time between trigger and LSA injection (default = 1000).");
		System.out.println("\t-f = The time it takes for a victim to generate Fightback (default = 50).");
		System.out.println("\t-m = MinLS Interval (default = 1000).");
		System.out.println("\t-r = Retransmission time (default = 5000).");
		System.out.println("All arguments except filename are optional, and must be positive values, if not stated defaults will be used.");
		return;
	}
	public static void runner(String file){
		String inputPath = "topologies\\"+file;
		String logPath =  "logs";
		String logFileName1 = inputPath.substring(11)+"_Effect_Scope.log";
		String logFileName2 = inputPath.substring(11)+"_Connected_Copmpnents.log";
		
		Experiment exp = null;
		try {
			exp = new Experiment(inputPath);
		} catch (FileNotFoundException e1) {
			System.err.println("File not found.");
			return;
		}
		
		try{
			//Check if logs directory exists and create it if not
			if (! (new File(logPath).isDirectory()) ) { new File(logPath).mkdir(); }
			
			//Create result logs and write table headers
			FileWriter fstream = new FileWriter(logPath + "\\" + logFileName1);
			BufferedWriter out = new BufferedWriter(fstream);
			out.write("Attacker\tSpoofed Router\tSize of Unaffected Group\tDiameter of Unaffected Group\n");
			out.close();
			
			fstream = new FileWriter(logPath + "\\" + logFileName2);
			out = new BufferedWriter(fstream);
			out.write("Attacker\tVictim\tSize of Spoofed Group\tDiameter of Spoofed Group\n");
			out.close();
		} catch (Exception e){//Catch exception if any
			System.err.println("Experiment Execution Error - At log file creation: " + e.getMessage());
			return;
		}
		
		//Loop for all combinations of attacker/victim
		for (int attacker = 0 ; attacker < Experiment.numOfRouters; attacker++){
			if (Common.debug) System.out.println("attacker:"+attacker);			
			for (int victim = 0 ; victim < Experiment.numOfRouters; victim++){
				if (attacker == victim) continue;
				exp.run(attacker, victim);
				exp.generateReportScope(logPath + "\\" + logFileName1);
			}
		}
		if (Common.debug) System.out.println("Kirov reporting");
		exp.generateReportGroup(logPath + "\\" + logFileName2);
		
		System.out.println("Done running experiments :)");
		return;
	}
	
}
